home *** CD-ROM | disk | FTP | other *** search
- /*
- -----------------------------------------------------------------------------
- BLOB MODELER
- By Alfonso Hermida and Steve Anger Dates: 12/16/93 ~ 2/15/94
-
- -----------------------------------------------------------------------------
- */
-
- #include <dos.h>
- #include <graphics.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <conio.h>
- #include <math.h>
- #include <ctype.h>
-
- #define TOL 0.0005
- #define PI 3.14159265358979323846
-
- #define FULLSCREEN_VIEW setviewport(0,0,getmaxx(),getmaxy(),1);
-
- #define FRONT_ID 0
- #define SIDE_ID 1
- #define TOP_ID 2
- #define ISO_ID 3
-
- #define FRONT_VIEW setviewport(1, 241, 239, 478, 1);
- #define SIDE_VIEW setviewport(241, 241, 478, 478,1);
- #define TOP_VIEW setviewport(1, 1, 239, 239, 1);
- #define ISO_VIEW setviewport(241, 1, 478, 239, 1);
-
- #define FRONT_AREA 0
- #define SIDE_AREA 1
- #define TOP_AREA 2
- #define ISO_AREA 3
- #define MENU_AREA 4
-
- #define TEXT_INPUT 1
- #define NUMBER_INPUT 0
-
- #define UP 1
- #define DOWN 0
-
- typedef struct {
- int x,y,width,height;
- int color;
- char str[81];
- } Icon;
-
- typedef struct {
- float x,y,z;
- } POINT3D;
-
- typedef struct {
- int x,y;
- } POINTint;
-
- typedef struct {
- POINT3D from, up, at;
- float angle;
- }Window3D;
-
- typedef struct {
- float Hmin, Vmin, Hmax, Vmax;
- }WorldLimits;
-
- typedef struct {
- float x,y,z;
- float radius, strength;
- } BLOB;
-
- typedef struct {
- POINT3D p1, p2;
- } PAIR3D;
-
-
- typedef struct {
- float value;
- POINT3D loc;
- } SAMPLE;
-
- typedef struct {
- float rmin, cmin,
- rowstep,colstep,
- PlaneDist;
- int rows, cols;
- char PerpTo;
- } GRID;
-
-
- // MOUSE ROUTINES
- int IsMouse (void);
- int MouseClick (void);
- void MouseXY (int *xpos, int *ypos);
- void MouseShow (int toggle);
- int WhereIsMouse(int x, int y);
- void UpdateMousePos(int xpos,int ypos,int status);
-
- // ICON ROUTINES
- Icon CreateIcon(int xo,int yo,int width,int height,int color,char * text);
- void DrawIcon (Icon ic);
- int IconCheck (Icon ikon, int xm, int ym);
- void DrawIconHiLite(Icon ic, int UpDown);
- void CreateIconColumn (int xo, int yo, int width, int height, int color, int
- spc, int num, Icon icon[], char **text);
- void CreateIconRow(int xo,int yo,int width,int height,int color,
- int spc, int num, Icon icon[],char **text);
-
- // WINDOW ROUTINES
- void InitGraphics(void);
- void SetWindow3D(int vp, int size);
- void SetViewpoint(void);
- void clearWindow(int vp);
- void WorldToDevice(double xw, double yw, int *xpc, int *ypc);
- void ScreenToWorld(int mx, int my, float *wx, float *wy);
- void World2DToDevice(POINT3D pp,int *xd, int *yd);
- POINTint World3DToDevice(POINT3D v1);
- void GetGridPoint2D(GRID g, int mx,int my, float * wx, float * wy);
- POINT3D GetPoint3D(int mx, int my);
-
-
- // 3D DRAWING ROUTINES
- void drawpoint3D(POINT3D *v1);
- void drawline3D(POINT3D *v1, POINT3D *v2);
- void DrawAxes(void);
- void drawsphere (int WinNum, POINT3D pc,float R);
-
-
- // VECTOR ROUTINES
- POINT3D add(POINT3D *a,POINT3D *b);
- POINT3D subtract(POINT3D *at,POINT3D *from);
- float mag(POINT3D *v);
- int equal(POINT3D *a, POINT3D *b);
- POINT3D multiply(POINT3D *v,float f);
- POINT3D divide(POINT3D *v,float d);
- POINT3D cross(POINT3D *v1, POINT3D *v2);
-
-
- // MISCELLANEOUS ROUTINES
- float DegToRad(float deg);
- void AllocateInputBox(void);
- void EraseInputBox(void);
- char * InputBox(char *s);
- char* KeyInput(char* str,int text);
- char* prompt (int x,int y);
- int YesNoCMD(char *s);
- void InfoBox(char *s);
-
-
- // BLOB ROUTINES
- float BlobFunc (POINT3D p);
- int AllocateCubes (void);
- void FreeCubes (void);
- void SampleLevel (SAMPLE **level, int ix, POINT3D *vmin, POINT3D *vmax);
- int CreateBlobs (void);
- void CubeIntersect (int iy, int iz);
- void FaceIntersect (SAMPLE *cube, int a, int b, int c, int d, PAIR3D *line, int *
- numline);
- void EdgeIntersect (POINT3D *v, SAMPLE *a, SAMPLE *b);
- void DrawBlobs(BLOB b, int vp);
-
-
- // MENU COMMANDS
- void ExecCommand(int c, int mx, int my, int use_xy, int btnprss);
- void CreateABlob(int mx, int my, int use_xy, int btn);
- void SelectABlob(int mx, int my, int use_xy, int btn);
- void CenterAView(int mx, int my, int use_xy, int btn);
- void Zoom(int mx, int my, int use_xy, int btn);
- void MoveABlob(int mx, int my, int use_xy, int btn, int copy);
- void WriteToPolyray(void);
- void WriteToPoV(void);
- void DeleteBlob(int mx, int my, int use_xy, int btn);
- void LoadAFile(char *str);
- void SaveAFile(char *str);
- void RedrawALL(void);
- void SetStrength(int mx, int my, int use_xy, int btn);
- void SetCamera(void);
- void ResizeABlob(int mx, int my, int use_xy, int btn);
- void drawgrid (int cw, GRID g);
-
-
- //----------------
- union REGS inregs; // mouse related
- union REGS outregs; // mouse related
-
-
- extern unsigned _stklen = 8000;
-
- // Global Info For Drawing
- POINT3D from, up, at; //viewing parameters
- POINT3D a1, a2, a3; //used in transforming coordinates
- int DeviceBottom, DeviceTop, //boundaries of viewing area
- DeviceLeft, DeviceRight;
- float a, b, c, d, DVal;
- float angle; //viewing angle
- float offset_x, offset_y, offset_z; //transform variables
- int ViewPort; // Current Selected ViewPort
- int BlobSel = 0; // selected blob
- int BlobSelOld = 0;
- int SaveRAW = 0; // RAW
- WorldLimits World[3];
- char FileName[80]; // current file loaded
- FILE *RAWfptr; // for saving RAW data faster
-
- float threshold = 0.6;
- int bnum = 0; // number of blobs
-
- #define MAXBLOB 500
- BLOB blobs[MAXBLOB+1];
- int LastCMD = -1; // last command select
- void *BitMap;
-
- GRID grid[3]; // grids for 3 views
- int GridRowCol = 20; // divisions on grid
- int GridStatus = 0; // show grid?
- int SnapStatus = 0; // show grid/snap?
-
- SAMPLE **level0 = NULL;
- SAMPLE **level1 = NULL;
- int x_steps = 30;
- int y_steps = 30;
- int z_steps = 30;
- int hide_backface = 1; /* 0 = see through, 1 = front faces only */
-
- #define IconNum 25
- //---------------------------------------------------------------------
- void main(void)
- {
- int i, mx, my, mxold = -1, myold = -1, status, status2, btn=0 ;
- Icon icon[IconNum];
- #define KLR LIGHTBLUE
- icon[2] = CreateIcon(483, 3,72,15,KLR," Create");
- icon[4] = CreateIcon(483, 21,72,15,KLR," Resize");
- icon[3] = CreateIcon(483, 39,72,15,KLR," Move");
- icon[24] = CreateIcon(483, 57,72,15,KLR," Copy");
- icon[9] = CreateIcon(483, 75,72,15,KLR," Delete");
- icon[13] = CreateIcon(483, 93,72,15,KLR," Density");
- #undef KLR
-
- #define KLR CYAN
- icon[0] = CreateIcon(560, 3,72,15,KLR," Load");
- icon[18] = CreateIcon(560, 21,72,15,KLR," New");
- icon[1] = CreateIcon(560, 39,72,15,KLR," Save");
- icon[5] = CreateIcon(560, 57,72,15,KLR," Povray");
- icon[6] = CreateIcon(560, 75,72,15,KLR," Polyray");
- icon[7] = CreateIcon(560, 93,72,15,KLR," RAW");
- #undef KLR
-
- #define KLR CYAN
- icon[16] = CreateIcon(483, 129,72,15,KLR," Redraw");
- icon[10] = CreateIcon(483, 147,72,15,KLR," Pan");
- icon[23] = CreateIcon(483, 165,72,15,KLR," Origin");
- icon[8] = CreateIcon(483, 183,72,15,KLR," Zoom");
-
- #undef KLR
-
- #define KLR LIGHTBLUE
- icon[20] = CreateIcon(560, 129,72,15,KLR," Snap");
- icon[21] = CreateIcon(560, 147,72,15,KLR," Grid");
- icon[22] = CreateIcon(560, 165,72,15,KLR," Row/Col");
- #undef KLR
-
- #define KLR RED
- icon[19] = CreateIcon(515, 288,100,15,KLR," Threshold");
- icon[12] = CreateIcon(483, 306,72,15,KLR," Preview");
- icon[17] = CreateIcon(560, 306,72,15,KLR," Detail");
- icon[11] = CreateIcon(515, 324,100,15,KLR," Camera");
- #undef KLR
-
- icon[14] = CreateIcon(500, 450,72,15,7," Quit");
- icon[15] = CreateIcon(580, 450,40,15,7," Who");
-
-
- // FRONT DEFAULT VALUES
- World[0].Hmin = -2;
- World[0].Vmin = -2;
- World[0].Hmax = 2;
- World[0].Vmax = 2;
- // SIDE DEFAULT VALUES
- World[1].Hmin = -2;
- World[1].Vmin = -2;
- World[1].Hmax = 2;
- World[1].Vmax = 2;
- // TOP DEFAULT VALUES
- World[2].Hmin = -2;
- World[2].Vmin = -2;
- World[2].Hmax = 2;
- World[2].Vmax = 2;
- // ISO DEFAULT VALUES
- from.x = 1; from.y = 1; from.z = -2.5;
- at.x = 0; at.y = 0; at.z = 0;
- up.x = 0; up.y = 1; up.z = 0;
- angle = DegToRad(45);
-
-
-
- InitGraphics();
- if (!IsMouse()) {
- closegraph(); printf("MOUSE driver not installed!"); exit(1);
- }
- setcolor(7);
- rectangle(0,0,getmaxy(),getmaxy());
- line(1,240,getmaxy(),240);
- line(240,1,240,getmaxy());
- setcolor(15);
- setfillstyle(1, 7);
- bar3d(481,0,getmaxx(),getmaxy(),0,0);
- for(i=0;i<IconNum;i++) DrawIcon(icon[i]);
- setcolor(15);
- setfillstyle(1, 15);
- bar3d(530,260,610,275,0,0);
- setcolor(0);
- outtextxy(531, 262, "SNAP OFF");
- outtextxy(490, 355, "Blob Sculptor 1.0a");
- setcolor(WHITE);
- outtextxy(491, 356, "Blob Sculptor 1.0a");
-
- strcpy(FileName,"");
- RedrawALL();
- status = 0;
- setcolor(WHITE);
- MouseShow(1);
- do {
- do {MouseXY (&mx, &my);
- if((mx != mxold) || (my != myold)) {
- UpdateMousePos(mx,my,0);
- mxold = mx;
- myold = my;
- }
- btn = MouseClick();
- }while(!btn);
-
- for (i=0;i<IconNum;i++) {
- status = IconCheck(icon[i],mx,my);
- if (status) {
- DrawIconHiLite(icon[i], DOWN);
- if (LastCMD > -1) DrawIconHiLite(icon[LastCMD],UP);
- if (i == 14) {
- status = 14;
- break;
- }
- else {
- LastCMD = i;
- ExecCommand(i, mx, my, 0, btn);
- }
- }
- }
- if (!status) { // If an icon command wasn't executed
- status2 = WhereIsMouse(mx,my);
- if ((status2 == FRONT_AREA) ||
- (status2 == SIDE_AREA) ||
- (status2 == TOP_AREA) ||
- (status2 == ISO_AREA)) ExecCommand(LastCMD, mx, my, 1, btn);
- }
- if ((LastCMD == 0) ||
- (LastCMD == 1) ||
- (LastCMD == 5) ||
- (LastCMD == 6) ||
- (LastCMD == 7) ||
- (LastCMD == 12) ||
- ((LastCMD > 13) && (LastCMD <= 22))) {
- FULLSCREEN_VIEW
- delay(50);
- DrawIconHiLite(icon[LastCMD],UP);
- LastCMD = -1;
- }
- }while(status != 14);
- closegraph();
- exit(1);
-
- }
- /////////////////////////////////////////////////////////////////////
-
- void UpdateGridStatus(int vp)
- {
- grid[vp].rmin = World[vp].Vmin;
- grid[vp].cmin = World[vp].Hmin;
- grid[vp].rowstep = (fabs(World[vp].Vmin)+ fabs(World[vp].Vmax)) / (1.0 * GridRowCol);
- grid[vp].colstep = (fabs(World[vp].Hmin)+ fabs(World[vp].Hmax)) / (1.0 * GridRowCol);
- grid[vp].PlaneDist = 0.0;
- grid[vp].rows = GridRowCol;
- grid[vp].cols = GridRowCol;
- switch(vp) {
- case 0: grid[vp].PerpTo = 'Z';break;
- case 1: grid[vp].PerpTo = 'X';break;
- case 2: grid[vp].PerpTo = 'Y';break;
- case 3: grid[vp].PerpTo = 'Z';break;
- }
- }
-
- void CreateIconRow(int xo,int yo,int width,int height,int color,
- int spc, int num, Icon icon[],char **text)
- {
- int i,x;
- x = xo;
- for(i=0;i<num;i++) {
- icon[i] = CreateIcon(x,yo,width,height,color,text[i]);
- x += width + spc;
- }
- }
-
- int YesNoCMD(char *s)
- {
- char *str[2] = {" Yes"," No"};
- Icon icon[2];
- int i,xpos,ypos,status,choice = 0;
-
- CreateIconRow(180,200,55,15,LIGHTGRAY,60,2,icon,str);
- MouseShow(0);
- FULLSCREEN_VIEW
- setfillstyle(1,LIGHTGRAY);
- bar3d(150,150,400,220,0,0);
- for(i=0;i<2;i++) DrawIcon(icon[i]);
- setcolor(0);
- outtextxy(160,160,s);
- MouseShow(1);
- do {MouseXY(&xpos, &ypos); }while(!MouseClick());
-
- for(i=0;i<2;i++) {
- status = IconCheck(icon[i],xpos,ypos);
- if (status) {
- switch(i) {
- case 0: choice = 1;break;
- case 1: choice = 0;break;
- }
- }
- }
- return(choice);
- }
-
-
- void InfoBox(char *s)
- {
- int xpos,ypos;
- MouseShow(0);
- FULLSCREEN_VIEW
- setfillstyle(1,LIGHTGRAY);
- bar3d(100,100,120 + strlen(s) * textwidth("W") ,100 + 6 * textheight("W"),0,0);
- setcolor(0);
- outtextxy(110,110,s);
- MouseShow(1);
- do {MouseXY(&xpos, &ypos); }while(!MouseClick());
- }
-
-
- void ResizeABlob(int mx, int my, int use_xy, int btn)
- {
- int i, mxold=0, myold=0;
- POINT3D p1, p2, v;
- BLOB tmp, tmpold;
-
- SelectABlob(mx, my, use_xy, btn);
- if (BlobSel) {
- tmp = blobs[BlobSel];
- tmpold = tmp;
- p1.x = tmp.x; p1.y = tmp.y; p1.z = tmp.z;
- setcolor(WHITE);
- MouseShow(0);
- for(i=0;i<4;i++) {
- SetWindow3D(i,0);
- DrawBlobs(blobs[BlobSel],i);
- }
- MouseShow(1);
- do {MouseXY (&mx, &my);
- if((mx != mxold) || (my != myold)) {
- UpdateMousePos(mx,my,0);
- mxold = mx;
- myold = my;
- }
- p2 = GetPoint3D(mx,my);
- v = subtract(&p2, &p1);
-
- tmp.radius = mag(&v)/sqrt(1.0 - sqrt(threshold/fabs(tmp.strength)));
-
- MouseShow(0);
- setwritemode(1);
- setcolor(WHITE);
- for(i=0;i<3;i++) {
- SetWindow3D(i,0);
- DrawBlobs(tmpold,i);
- DrawBlobs(tmp,i);
- }
- setwritemode(0);
- MouseShow(1);
- tmpold = tmp;
- btn = MouseClick();
- }while(!btn);
- if (btn == 1) blobs[BlobSel] = tmp;
- RedrawALL();
- }
- }
-
-
- void SetCamera(void)
- {
- int i,j,c,ok = 0,xpos,ypos;
- char *str[11] = {" From X", " From Y", " From Z",
- " To X", " To Y", " To Z",
- " Up X", " Up Y", " Up Z",
- " OK ", " Cancel "};
- Icon Col[11];
- char terms[9][80], s[80], s2[40];
- FULLSCREEN_VIEW
- MouseShow(0);
- CreateIconColumn(75,100,60,15,LIGHTGRAY,5,11,Col,str);
- for(i=9;i<11;i++) {
- Col[i].x = Col[i-9].x + 300;
- Col[i].y = Col[i-9].y;
- }
- sprintf(s2,"%g",from.x); strcpy(terms[0],s2);
- sprintf(s2,"%g",from.y); strcpy(terms[1],s2);
- sprintf(s2,"%g",from.z); strcpy(terms[2],s2);
- sprintf(s2,"%g", at.x); strcpy(terms[3],s2);
- sprintf(s2,"%g", at.y); strcpy(terms[4],s2);
- sprintf(s2,"%g", at.z); strcpy(terms[5],s2);
- sprintf(s2,"%g", up.x); strcpy(terms[6],s2);
- sprintf(s2,"%g", up.y); strcpy(terms[7],s2);
- sprintf(s2,"%g", up.z); strcpy(terms[8],s2);
-
- setcolor(0);
- setfillstyle(1,LIGHTGRAY);
- bar3d(60,85,Col[9].x + 70,Col[8].y + 30,0,0);
- for(i=0;i<11;i++) DrawIcon(Col[i]);
- outtextxy((Col[9].x + 10)/2 + 60,88,"CAMERA");
- MouseShow(1);
- do {
- MouseShow(0);
- setcolor(LIGHTGRAY);
- setfillstyle(1,LIGHTGRAY);
- bar3d(Col[0].x+62,Col[0].y,Col[9].x - 2,Col[8].y + 15,0,0);
-
- setcolor(0);
- for(c=0;c<9;c++) outtextxy(Col[c].x + 70,Col[c].y + 3,terms[c]);
-
- MouseShow(1);
- do { MouseXY(&xpos, &ypos);
- }while(!MouseClick());
- for(i=0;i<11;i++) {
- j = IconCheck(Col[i],xpos,ypos);
- if (j) {
- if ((i>=0) && (i<=8)) {
- MouseShow(0);
- strcpy(s,KeyInput(Col[i].str,NUMBER_INPUT));
- MouseShow(1);
- if (strlen(s)) strcpy(terms[i],s);
- }
- else {
- if (i==9) ok = 1;
- if (i==10) ok = -1;
- }
- }
- }
- }while(ok == 0);
-
- if (ok == 1) {
- from.x = atof(terms[0]); from.y = atof(terms[1]); from.z = atof(terms[2]);
- at.x = atof(terms[3]); at.y = atof(terms[4]); at.z = atof(terms[5]);
- up.x = atof(terms[6]); up.y = atof(terms[7]); up.z = atof(terms[8]);
- }
- RedrawALL();
- }
-
-
- void SetStrength(int mx, int my, int use_xy, int btn)
- {
- char str[80],pstr[80];
- SelectABlob(mx,my,use_xy,btn);
- FULLSCREEN_VIEW
- if (BlobSel) {
- sprintf(pstr,"Strength: [%g]",blobs[BlobSel].strength);
- strcpy(str,KeyInput(pstr,NUMBER_INPUT));
- if (strcmp(str,"")) blobs[BlobSel].strength = atof(str);
- }
- }
-
-
- void RedrawALL(void)
- {
- int i,j;
- FULLSCREEN_VIEW
- MouseShow(0);
- setcolor(7);
- rectangle(0,0,getmaxy(),getmaxy());
- line(1,240,getmaxy(),240);
- line(240,1,240,getmaxy());
- setcolor(WHITE);
- for (i=0;i<4;i++) {
- SetWindow3D(i,0);
- clearviewport();
- UpdateGridStatus(i); // must be updated ALWAYS!
- if (GridStatus && (i < 3)) {
- setcolor(LIGHTGRAY);
- drawgrid(i,grid[i]);
- }
- DrawAxes();
- setcolor(WHITE);
- if (bnum) {
- for(j=1;j<=bnum;j++) {
- if (blobs[j].strength < 0) setcolor(LIGHTRED);
- else setcolor(WHITE);
- DrawBlobs(blobs[j],i);
-
- }
- }
- }
- setcolor(WHITE);
- MouseShow(1);
- }
-
-
- void AllocateInputBox(void)
- {
- unsigned size;
- size = imagesize(200,200,500,300);
- if ((BitMap = (void *)malloc(size)) == NULL)
- {
- printf("Not enough memory to allocate buffer!\n");
- exit(1);
- }
- MouseShow(0);
- getimage(200,200,500,300,BitMap);
- MouseShow(1);
- }
-
-
- void EraseInputBox(void)
- {
- MouseShow(0);
- putimage(200,200,BitMap,COPY_PUT);
- free(BitMap);
- MouseShow(1);
- }
-
-
- char * InputBox(char *s)
- {
- static char ans[80];
- MouseShow(0);
- AllocateInputBox();
- setfillstyle(1,LIGHTGRAY);
- bar3d(200,200,500,300,0,0);
- setcolor(15);
- rectangle(200,200,500,300);
- rectangle(205,300-2*textheight("W")-5,495,295);
- setcolor(0);
- outtextxy(205,205,s);
- MouseShow(1);
- strcpy(ans,prompt(207,300-2*textheight("W")-3));
- MouseShow(0);
- EraseInputBox();
- MouseShow(1);
- return(ans);
- }
-
-
- char* KeyInput(char* str,int text)
- {
- static char str1[80];
- int i,error;
-
- do
- {
- error = 0;
- strcpy(str1,InputBox(str));
- if (text==0)
- {
- for (i=0;i<strlen(str1);i++)
- if ((!isdigit(str1[i])) && (str1[i] != '.')
- && (toupper(str1[i]) != 'E') && (str1[i] != '-'))
- error = 1;
- }
- else {
- for (i=0;i<strlen(str1);i++)
- if (str1[i] == ' ') error = 1;
- }
- }while(error);
- return (str1);
- }
-
- char* prompt (int x,int y)
- {
- char KeyChar,key[2];
- static char word[80];
- int j, erase, stop,TW = textwidth("W"),TH = textheight("W")+1;
- j = 0;
- setcolor(0);
- erase = stop = 0;
- key[1] = '\0';
- do
- {
- KeyChar = getch();
- key[0] = KeyChar;
- if (KeyChar == 13) stop = 1;
- if ((KeyChar == 8) && (j > 0)) erase = 1;
- if (KeyChar == 0) {
- KeyChar = getch();
- if (((KeyChar == 75) || (KeyChar == 83)) && (j > 0)) erase = 1;
- }
- if (stop) word[j] = '\0';
- else
- if (erase) {
- if (j) {
- j --;
- MouseShow(0);
- bar(x+TW*j,y,x+TW*(j+2),y+TH);
- outtextxy(x+TW*j,y,"_");
- MouseShow(1);
- }
- erase = 0;
- }
- else {
- if(j<34) {
- MouseShow(0);
- bar(x+TW*j,y,x+TW*(j+2),y+TH);
- outtextxy(x+TW*j,y,key);
- outtextxy(x+TW*(j+1),y,"_");
- MouseShow(1);
- word[j] = key[0];
- j++;
- }
- }
- }while(!stop);
-
- return(word);
- }
-
-
- void LoadAFile(char *str)
- {
- FILE *fptr;
- float x,y,z,r,s;
- if ( (fptr = fopen(str,"r")) == NULL) {
- InfoBox("Can't load the file!");
- RedrawALL();
- }
- else {
- bnum = 0;
- fscanf(fptr,"%f",&threshold);
- while (!feof(fptr)) {
- if ((fscanf(fptr,"%f",&x) > 0) &&
- (fscanf(fptr,"%f",&y) > 0) &&
- (fscanf(fptr,"%f",&z) > 0) &&
- (fscanf(fptr,"%f",&s) > 0) &&
- (fscanf(fptr,"%f",&r) > 0) &&
- (r > TOL) &&
- (bnum < MAXBLOB)) {
- bnum++;
- blobs[bnum].x = x;
- blobs[bnum].y = y;
- blobs[bnum].z = z;
- blobs[bnum].radius = r;
- blobs[bnum].strength = s;
- }
- }
- fclose(fptr);
- strcpy(FileName,str);
- }
- }
-
- void SaveAFile(char *str)
- {
- FILE *fptr;
- int i=1;
- char s[40];
- sprintf(s,"Overwrite < %s > ?",str);
- if ((fptr = fopen(str,"r")) != NULL) i = YesNoCMD(s);
- fclose(fptr);
- if (i) {
- if ((fptr = fopen(str,"w+t")) == NULL) {
- InfoBox("Can't open the file for output!");
- RedrawALL();
-
- }
- else {
- if(bnum) {
- MouseShow(0);
- fprintf(fptr,"%g\n",threshold);
- for(i=1;i<=bnum;i++)
- if (blobs[i].radius > TOL)
- fprintf(fptr,"%g %g %g %g %g\n",blobs[i].x,blobs[i].y,blobs[i].z,
- blobs[i].strength,blobs[i].radius);
- fclose(fptr);
- MouseShow(1);
- }
- }
- }
- RedrawALL();
- }
-
-
-
- void DeleteBlob(int mx, int my, int use_xy, int btn)
- {
- int i;
- SelectABlob(mx, my, use_xy, btn);
- if (BlobSel) {
- if (YesNoCMD("Delete Blob?")) {
- if (BlobSel && bnum ) {
- if (BlobSel == bnum)
- bnum--;
- else {
- for(i = BlobSel; i<bnum; i++) blobs[i] = blobs[i+1];
- bnum--;
- }
- }
- }
- RedrawALL();
- }
- }
-
- void WriteToPoV(void)
- {
- FILE *fptr;
- char str[80];
- int i;
- if (bnum) {
-
- MouseShow(0);
- strcpy(str,KeyInput("Save As < BLOB.POV >",TEXT_INPUT));
- if (strlen(str) == 0) strcpy(str,"BLOB.POV");
- MouseShow(1);
-
- fptr = fopen(str, "w+");
- fprintf(fptr,"#include \"colors.inc\"\n");
- fprintf(fptr,"#include \"textures.inc\"\n");
- fprintf(fptr,"#include \"shapes.inc\"\n\n");
- fprintf(fptr,"\ncamera {\n");
- fprintf(fptr," location <%g, %g, %g>\n",from.x,from.y,from.z);
- fprintf(fptr," look_at <%g, %g, %g>\n",at.x,at.y,at.z);
- fprintf(fptr," up <%g, %g, %g>\n",up.x,up.y,up.z);
- fprintf(fptr,"}\n\n\n");
- fprintf(fptr,"light_source{< %g , %g , %g > color White }\n\n",
- from.x,from.y,from.z);
- fprintf(fptr,"blob {\n");
- fprintf(fptr," threshold %g\n",threshold);
- for(i=1;i<=bnum;i++) {
- if (blobs[i].radius < TOL) fprintf(fptr,"//");
- fprintf(fptr, " component %g, %g, <%g, %g, %g>\n", blobs[i].strength,
- blobs[i].radius,
- blobs[i].x,
- blobs[i].y,
- blobs[i].z);
- }
- fprintf(fptr, "\n texture {Gold_Metal}\n}\n");
- fclose(fptr);
- }
- }
-
- void WriteToPolyray(void)
- {
- FILE *fptr;
- char str[80];
- int i;
- if (bnum) {
- MouseShow(0);
- strcpy(str,KeyInput("Save As < BLOB.PI >",TEXT_INPUT));
- if (strlen(str) == 0) strcpy(str,"BLOB.PI");
- MouseShow(1);
- fptr = fopen(str, "w+");
- fprintf(fptr,"include \"colors.inc\"\n");
- fprintf(fptr,"include \"texture.inc\"\n");
- fprintf(fptr,"\nviewpoint {\n");
- fprintf(fptr," from <%g, %g, %g>\n",from.x,from.y,from.z);
- fprintf(fptr," at <%g, %g, %g>\n",at.x,at.y,at.z);
- fprintf(fptr," up <%g, %g, %g>\n",up.x,up.y,up.z);
- fprintf(fptr," angle 45\n resolution 200,200\n aspect 1.0\n}\n\n");
- fprintf(fptr,"light <%g, %g, %g>\n\n",from.x,from.y,from.z);
- fprintf(fptr,"object {\n");
- fprintf(fptr," blob %g:\n",threshold);
- for(i=1;i<=bnum;i++) {
- if (blobs[i].radius < TOL) fprintf(fptr,"//");
- fprintf(fptr, " sphere <%g, %g, %g>, %g, %g", blobs[i].x,
- blobs[i].y,
- blobs[i].z,
- blobs[i].strength,
- blobs[i].radius);
- if (i < bnum) fprintf(fptr,",\n");
- else fprintf(fptr,"\n");
- }
- fprintf(fptr, "\n shiny_yellow \n}\n");
- fclose(fptr);
- }
- }
-
-
- void Zoom(int mx, int my, int use_xy, int btn)
- {
-
- int i, mxold=0, myold=0, pos;
- float d;
- if(!use_xy) {
- do {MouseXY (&mx, &my);
- if((mx != mxold) || (my != myold)) {
- UpdateMousePos(mx,my,0);
- mxold = mx;
- myold = my;
- }
- btn = 0;
- btn = MouseClick();
- }while(!btn);
- }
- if (btn == 1) d = 0.5;
- else d = 2.0;
- pos = WhereIsMouse(mx,my);
- switch(pos) {
- case FRONT_AREA: //Y X
- World[0].Hmin *= d;
- World[0].Vmin *= d;
- World[0].Hmax *= d;
- World[0].Vmax *= d;
- break;
- case SIDE_AREA: // Y Z
- World[1].Hmin *= d;
- World[1].Vmin *= d;
- World[1].Hmax *= d;
- World[1].Vmax *= d;
- break;
- case TOP_AREA: // Z X
- World[2].Hmin *= d;
- World[2].Vmin *= d;
- World[2].Hmax *= d;
- World[2].Vmax *= d;
- break;
- case ISO_AREA: // ISO
- from.x *= d;
- from.y *= d;
- from.z *= d;
- break;
-
- }
- if (pos != MENU_AREA) {
- MouseShow(0);
- SetWindow3D(pos,0);
- clearviewport();
- UpdateGridStatus(pos);
- if ((pos < 3) && GridStatus) {
- setcolor(LIGHTGRAY);
- drawgrid(1,grid[pos]);
- }
- DrawAxes();
- for(i=1;i<=bnum;i++) {
- if (blobs[i].strength < 0) setcolor(LIGHTRED);
- else setcolor(WHITE);
- DrawBlobs(blobs[i],pos);
- }
- MouseShow(1);
- }
- setcolor(WHITE);
- }
- void CenterAView(int mx, int my, int use_xy, int btn)
- {
- int i, mxold=0, myold=0, pos;
- POINT3D p0, p1;
- btn++; // quiet the compiler!
- if(!use_xy) {
- do {MouseXY (&mx, &my);
- if((mx != mxold) || (my != myold)) {
- UpdateMousePos(mx,my,0);
- mxold = mx;
- myold = my;
- }
- }while(!MouseClick());
- }
- p1 = GetPoint3D(mx,my);
- pos = WhereIsMouse(mx,my);
- switch(pos) {
- case FRONT_AREA: //Y X
- p0.x = (World[0].Hmin + World[0].Hmax) / 2.0;
- p0.y = (World[0].Vmin + World[0].Vmax) / 2.0;
- p0.x = p1.x - p0.x;
- p0.y = p1.y - p0.y;
- World[0].Hmin += p0.x;
- World[0].Vmin += p0.y;
- World[0].Hmax += p0.x;
- World[0].Vmax += p0.y;
- break;
- case SIDE_AREA: // Y Z
- p0.z = (World[1].Hmin + World[1].Hmax) / 2.0;
- p0.y = (World[1].Vmin + World[1].Vmax) / 2.0;
- p0.z = p1.z - p0.z;
- p0.y = p1.y - p0.y;
- World[1].Hmin += p0.z;
- World[1].Vmin += p0.y;
- World[1].Hmax += p0.z;
- World[1].Vmax += p0.y;
- break;
- case TOP_AREA: // Z X
- p0.x = (World[2].Hmin + World[2].Hmax) / 2.0;
- p0.z = (World[2].Vmin + World[2].Vmax) / 2.0;
- p0.x = p1.x - p0.x;
- p0.z = p1.z - p0.z;
- World[2].Hmin += p0.x;
- World[2].Vmin += p0.z;
- World[2].Hmax += p0.x;
- World[2].Vmax += p0.z;
- break;
-
- }
- if( (pos != MENU_AREA)) {
- MouseShow(0);
- SetWindow3D(pos,0);
- UpdateGridStatus(pos);
- clearviewport();
- if ((pos < 3) && GridStatus) {
- setcolor(LIGHTGRAY);
- drawgrid(1,grid[pos]);
- }
- DrawAxes();
- for(i=1;i<=bnum;i++) {
- if (blobs[i].strength < 0 ) setcolor(LIGHTRED);
- else setcolor(WHITE);
- DrawBlobs(blobs[i],pos);
- }
- MouseShow(1);
- }
- setcolor(WHITE);
- }
-
- void CreateABlob(int mx, int my, int use_xy, int btn)
- {
- int i, mxold=0, myold=0, FLAG = 0;
- POINT3D p1, p2, v;
- BLOB tmp, tmpold;
- if (bnum <MAXBLOB) {
- setcolor(WHITE);
- if(!use_xy) {
- do {MouseXY (&mx, &my);
- if((mx != mxold) || (my != myold)) {
- UpdateMousePos(mx,my,0);
- mxold = mx;
- myold = my;
- }
- btn = MouseClick();
- }while(!btn);
- }
- if (btn == 1) {
- p1 = GetPoint3D(mx,my);
-
- do {MouseXY (&mx, &my);
- if((mx != mxold) || (my != myold)) {
- UpdateMousePos(mx,my,0);
- mxold = mx;
- myold = my;
- }
- p2 = GetPoint3D(mx,my);
- tmp.x = p1.x;
- tmp.y = p1.y;
- tmp.z = p1.z;
- v = subtract(&p2, &p1);
-
- tmp.strength = 1.0;
- tmp.radius = mag(&v)/sqrt(1.0 - sqrt(threshold/fabs(tmp.strength)));
-
- MouseShow(0);
- setwritemode(1);
- for(i=0;i<3;i++) { SetWindow3D(i,0); DrawBlobs(tmp,i); }
- setwritemode(0);
- MouseShow(1);
- if (!FLAG) FLAG = 1;
- else {
- MouseShow(0);
- setwritemode(1);
- for(i=0;i<3;i++) { SetWindow3D(i,0); DrawBlobs(tmpold,i); }
- setwritemode(0);
- MouseShow(1);
- }
- tmpold = tmp;
- btn = MouseClick();
- }while(!btn);
- if (btn == 1) {
- bnum++;
- blobs[bnum] = tmp;
- }
- RedrawALL();
- } //if LMB was pressed do not create the center point!
- }// if bnum < MAXBLOB
- }
-
- void MoveABlob(int mx, int my, int use_xy, int btn, int copy)
- {
- int i, mxold=0, myold=0,pos;
- POINT3D p2;
- BLOB tmp, tmpold;
-
- SelectABlob(mx,my,use_xy,btn);
- if (BlobSel) {
- tmp = blobs[BlobSel];
- tmpold = tmp;
- do {MouseXY (&mx, &my);}while(!MouseClick());
-
- setcolor(WHITE);
- MouseShow(0);
- for(i=0;i<4;i++) {
- SetWindow3D(i,0);
- DrawBlobs(blobs[BlobSel],i);
- }
- MouseShow(1);
- do {MouseXY (&mx, &my);
- if((mx != mxold) || (my != myold)) {
- UpdateMousePos(mx,my,0);
- mxold = mx;
- myold = my;
- }
- p2 = GetPoint3D(mx,my);
- pos = WhereIsMouse(mx,my);
- switch(pos) {
- case FRONT_AREA: tmp.x = p2.x; tmp.y = p2.y; break;
- case SIDE_AREA: tmp.y = p2.y; tmp.z = p2.z; break;
- case TOP_AREA: tmp.x = p2.x; tmp.z = p2.z; break;
- }
- MouseShow(0);
- setwritemode(1);
- setcolor(WHITE);
- for(i=0;i<3;i++) {
- SetWindow3D(i,0);
- DrawBlobs(tmpold,i);
- DrawBlobs(tmp,i);
- }
- setwritemode(0);
- MouseShow(1);
- tmpold = tmp;
- btn = MouseClick();
- }while(!btn);
-
- if (btn == 1) {
- if (!copy) blobs[BlobSel] = tmp;
- else {
- if (bnum < MAXBLOB) {bnum++; blobs[bnum] = tmp;}
- }
- }
- RedrawALL();
- }
- }
-
- void SelectABlob(int mx, int my, int use_xy, int btn)
- {
- int pos, i, mxold=0, myold=0;
- float dist, dist2, rr;
- POINT3D p1;
-
- setcolor(WHITE);
- if(!use_xy) {
- do {MouseXY (&mx, &my);
- btn = 0;
- if((mx != mxold) || (my != myold)) {
- UpdateMousePos(mx,my,0);
- mxold = mx;
- myold = my;
- }
- btn = MouseClick();
- }while(!btn);
- }
- if (btn==1) {
- p1 = GetPoint3D(mx,my);
- pos = WhereIsMouse(mx,my);
- dist = 3e30;
- BlobSel = 0;
- for(i=1;i<=bnum;i++) {
- switch(pos) {
- case FRONT_AREA:
- dist2 = (blobs[i].x - p1.x)*(blobs[i].x - p1.x) +
- (blobs[i].y - p1.y)*(blobs[i].y - p1.y);
- break;
- case SIDE_AREA:
- dist2 = (blobs[i].z - p1.z)*(blobs[i].z - p1.z) +
- (blobs[i].y - p1.y)*(blobs[i].y - p1.y);
- break;
- case TOP_AREA:
- dist2 = (blobs[i].x - p1.x)*(blobs[i].x - p1.x) +
- (blobs[i].z - p1.z)*(blobs[i].z - p1.z);
- break;
- default : dist2 = 3e30; break; //in case you select outside!
- }
-
- rr = blobs[i].radius * sqrt(1.0 - sqrt(threshold/fabs(blobs[i].strength)));
- dist2 -= rr * rr;
- dist2 = fabs(dist2);
- if (dist2 < dist) {
- dist = dist2;
- BlobSel = i;
- }
- }
-
- if (BlobSel) {
- MouseShow(0);
- for(i=0;i<4;i++) {
- SetWindow3D(i,0);
- setcolor(YELLOW);
- DrawBlobs(blobs[BlobSel],i);
- if(BlobSelOld && (BlobSelOld != BlobSel) && (BlobSelOld <= bnum)) {
- setcolor(WHITE);
- DrawBlobs(blobs[BlobSelOld],i);
- }
- }
- setcolor(WHITE);
- MouseShow(1);
- BlobSelOld = BlobSel;
- }
- }
- }
-
-
-
- void DrawBlobs(BLOB b, int vp)
- {
- POINT3D p;
- p.x = b.x;
- p.y = b.y;
- p.z = b.z;
-
- drawsphere (vp, p, b.radius * sqrt(1.0 - sqrt(threshold/fabs(b.strength))));
- }
-
- void ExecCommand(int c, int mx, int my, int use_xy, int btnprss)
- {
- FILE *fptr;
- char tfile[80], s[80];
- int i;
-
- switch(c) {
- //[0] " Load"
- case 0: strcpy(tfile,KeyInput("Load File:",TEXT_INPUT));
- LoadAFile(tfile);
- RedrawALL();
- break;
- //[1] " Save "
- case 1: MouseShow(0);
- sprintf(tfile,"Save As < %s >",FileName);
- strcpy(tfile,KeyInput(tfile,TEXT_INPUT));
- if (strlen(tfile) == 0) strcpy(tfile,FileName);
- MouseShow(1);
- SaveAFile(tfile);
- break;
- //[2] " Create"
- case 2: CreateABlob(mx, my, use_xy,btnprss); break;
- //[3] " Move"
- case 3: MoveABlob(mx, my, use_xy,btnprss,0); break;
- //[4] " Resize"
- case 4: if (bnum) ResizeABlob(mx, my, use_xy,btnprss) ;break;
- //[5] " Povray"
- case 5: MouseShow(0);
- WriteToPoV();
- MouseShow(1);
- break;
- //[6] " Polyray"
- case 6: MouseShow(0);
- WriteToPolyray();
- MouseShow(1);
- break;
- //[7] " RAW"
- case 7: SaveRAW = 1;
- hide_backface = 0;
- i = 1;
- MouseShow(0);
- strcpy(tfile,KeyInput("Save As < BLOB.RAW >",TEXT_INPUT));
- if (strlen(tfile) == 0) strcpy(tfile,"BLOB.RAW");
- MouseShow(1);
- sprintf(s,"Overwrite < %s > ?",tfile);
- if ((fptr = fopen(tfile,"r")) != NULL) {
- i = YesNoCMD(s);
- RedrawALL();
- }
- fclose(fptr);
- if (i) {
- fptr = fopen(tfile, "w+"); // open and close to clean up
- fclose(fptr); // any previous data
- setcolor(WHITE);
- SetWindow3D(ISO_ID, 0);
- MouseShow(0);
- RAWfptr = fopen(tfile, "a+");
- CreateBlobs();
- fclose(RAWfptr);
- MouseShow(1);
- }
- SaveRAW = 0;
- hide_backface = 1;
- break;
- //[8] " Zoom"
- case 8: Zoom(mx, my, use_xy,btnprss); break;
- //[9] " Delete"
- case 9: if (bnum) DeleteBlob(mx, my, use_xy,btnprss); break;
- //[10] " Center"
- case 10: CenterAView(mx, my, use_xy,btnprss); break;
- //[11] " Camera"
- case 11: SetCamera();
- break;
- //[12] " Preview"
- case 12: if(bnum) {
- setcolor(WHITE);
- SetWindow3D(ISO_ID, 0);
- MouseShow(0);
- CreateBlobs();
- MouseShow(1);
- }
- break;
- //[13] " Strength"
- case 13: if (bnum) SetStrength(mx, my, use_xy,btnprss);
- break;
- //[14] " Quit"
- case 14: break;
- //[15] " Who"
- case 15:InfoBox("By Alfonso Hermida/Steve Anger 2/94");
- RedrawALL();
- break;
- //[16] " Redraw"
- case 16: RedrawALL(); break;
- //[17] " Detail"
- case 17: FULLSCREEN_VIEW
- sprintf(tfile,"Detail Level <20 - 50> [%d]",x_steps);
- strcpy(tfile,KeyInput(tfile,NUMBER_INPUT));
- if (atoi(tfile) >= 20 && atoi(tfile) <= 50)
- x_steps = y_steps = z_steps = atoi(tfile);
- break;
- //[18] " New"
- case 18: if(YesNoCMD("Delete Database?")){
- bnum =0;
- strcpy(FileName,"");
- }
- RedrawALL();
- break;
- //[19] " Threshold"
- case 19: FULLSCREEN_VIEW
- sprintf(tfile,"Threshold Level (>0) [%g]",threshold);
- strcpy(tfile,KeyInput(tfile,NUMBER_INPUT));
- if (strlen (tfile) && atof(tfile) >= 0) threshold = atof(tfile);
- break;
- //[20] " Snap"
- case 20: FULLSCREEN_VIEW
- setcolor(15);
- setfillstyle(1,WHITE);
- bar3d(530,260,610,275,0,0);
- setcolor(0);
- if (SnapStatus) {
- SnapStatus = 0;
- outtextxy(531, 262, "SNAP OFF");
- }
- else {
- SnapStatus = 1;
- outtextxy(531, 262, "SNAP ON");
- }
- setcolor(WHITE);
- break;
- //[21] " Grid"
- case 21: if (GridStatus) GridStatus = 0;
- else GridStatus = 1;
- RedrawALL();
- break;
- //[22] "Row/Col"
- case 22: FULLSCREEN_VIEW
- sprintf(tfile,"Grid Rows/Cols (>3) [%d]",GridRowCol);
- strcpy(tfile,KeyInput(tfile,NUMBER_INPUT));
- if (strlen (tfile) && atoi(tfile) >= 3) {
- GridRowCol = atoi(tfile);
- RedrawALL();
- }
- break;
- //[23] " Origin"
- case 23: do {MouseXY (&mx, &my);}while(!MouseClick());
- i = WhereIsMouse(mx,my);
- if (i >= 0 && i <= 2) {
- World[i].Hmin = -2;
- World[i].Vmin = -2;
- World[i].Hmax = 2;
- World[i].Vmax = 2;
- RedrawALL();
- }
- break;
- //[24] " Copy"
- case 24: MoveABlob(mx, my, use_xy,btnprss,1); break;
- }
- }
-
- void DrawIconHiLite(Icon ic, int UpDown)
- {
- MouseShow(0);
- if(UpDown == DOWN) {
- setcolor(15);
- rectangle(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+ic.height-1);
- setcolor(0);
- line(ic.x,ic.y,ic.x+ic.width,ic.y);
- line(ic.x,ic.y,ic.x,ic.y+ic.height);
- line(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+1);
- line(ic.x+1,ic.y+1,ic.x+1,ic.y+ic.height-1);
- }
- else {
- setcolor(0);
- rectangle(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+ic.height-1);
- setcolor(15);
- line(ic.x,ic.y,ic.x+ic.width,ic.y);
- line(ic.x,ic.y,ic.x,ic.y+ic.height);
- line(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+1);
- line(ic.x+1,ic.y+1,ic.x+1,ic.y+ic.height-1);
- }
- MouseShow(1);
- setcolor(WHITE);
- }
-
-
- POINT3D GetPoint3D(int mx, int my)
- {
- POINT3D temp;
- float wx, wy;
- int k;
- k = WhereIsMouse(mx, my);
- SetWindow3D(WhereIsMouse(mx,my),0);
- switch(k) {
- case FRONT_AREA : mx = mx - 1 ; my = my - 241; break;
- case SIDE_AREA : mx = mx - 241; my = my - 241; break;
- case TOP_AREA : mx = mx - 1 ; my = my - 1; break;
- case ISO_AREA : mx = mx - 241; my = my - 1; break;
- }
- if (!SnapStatus)
- ScreenToWorld(mx, my, &wx, &wy);
- else
- if (k < 3) GetGridPoint2D(grid[k],mx, my, &wx, &wy);
-
- if (fabs(wx) < TOL) wx = 0.0;
- if (fabs(wy) < TOL) wy = 0.0;
-
- switch(k) {
- case FRONT_AREA : temp.x = wx; temp.y = wy; temp.z = 0.0; break;
- case SIDE_AREA : temp.x = 0.0; temp.y = wy; temp.z = wx; break;
- case TOP_AREA : temp.x = wx; temp.y = 0.0; temp.z = wy; break;
- case ISO_AREA : temp.x = wx; temp.y = wy; temp.z = 0.0; break;
- }
-
- return (temp);
- }
-
- void GetGridPoint2D(GRID g, int mx,int my, float * wx, float * wy)
- {
- int nx,ny;
- ScreenToWorld(mx,my,wx,wy);
- nx = (*wx - g.cmin) / (float)g.colstep + .5;
- ny = (*wy - g.rmin) / (float)g.rowstep + .5;
- *wx = g.cmin + nx * g.colstep;
- *wy = g.rmin + ny * g.rowstep;
- }
-
- void drawgrid (int cw, GRID g)
- {
- int j;
- float rmax,cmax;
- POINT3D p1,p2;
- cw++;
- setlinestyle(DOTTED_LINE,1,NORM_WIDTH);
- rmax = g.rmin+g.rowstep*(g.rows);
- cmax = g.cmin+g.colstep*(g.cols);
-
- // case = X _|_ X axis
- // Y _|_ Y axis
- // Z _|_ Z axis
- switch(toupper(g.PerpTo))
- {
- case 'X':
- for (j=0;j<g.cols+1;j++)
- {
- p1.x = g.PlaneDist;
- p1.y = rmax;
- p1.z = g.cmin+j*g.colstep;
- p2.x = g.PlaneDist;
- p2.y = g.rmin;
- p2.z = g.cmin+j*g.colstep;
- drawline3D(&p1,&p2);
- }
- for (j=0;j<g.rows+1;j++)
- {
- p1.x = g.PlaneDist;
- p1.y = g.rmin+j*g.rowstep;
- p1.z = cmax;
- p2.x = g.PlaneDist;
- p2.y = g.rmin+j*g.rowstep;
- p2.z = g.cmin;
- drawline3D(&p1,&p2);
- }
- break;
- case 'Y':
- for (j=0;j<g.cols+1;j++)
- {
- p1.z = rmax;
- p1.y = g.PlaneDist;
- p1.x = g.cmin+j*g.colstep;
- p2.z = g.rmin;
- p2.y = g.PlaneDist;
- p2.x = g.cmin+j*g.colstep;
- drawline3D(&p1,&p2);
- }
- for (j=0;j<g.rows+1;j++)
- {
- p1.z = g.rmin+j*g.rowstep;
- p1.y = g.PlaneDist;
- p1.x = g.cmin;
- p2.z = g.rmin+j*g.rowstep;
- p2.y = g.PlaneDist;
- p2.x = cmax;
- drawline3D(&p1,&p2);
-
- }
- break;
- case 'Z':
- for (j=0;j<g.cols+1;j++)
- {
- p1.x = g.cmin+j*g.colstep;
- p1.y = rmax;
- p1.z = g.PlaneDist;
- p2.x = g.cmin+j*g.colstep;
- p2.y = g.rmin,
- p2.z = g.PlaneDist;
- drawline3D(&p1,&p2);
- }
- for (j=0;j<g.rows+1;j++)
- {
- p1.x = g.cmin;
- p1.y = g.rmin+j*g.rowstep;
- p1.z = g.PlaneDist;
- p2.x = cmax;
- p2.y = g.rmin+j*g.rowstep;
- p2.z = g.PlaneDist;
- drawline3D(&p1,&p2);
- }
- break;
- }
- setlinestyle(SOLID_LINE,1,NORM_WIDTH);
- }
-
-
- void UpdateMousePos(int xpos,int ypos,int status)
- {
- int k;
- float wx,wy;
- char s[80], vpl[5];
- strcpy(vpl,"");
- k = WhereIsMouse(xpos, ypos);
- switch(k) {
- case FRONT_AREA : SetWindow3D(FRONT_ID,0);
- xpos = xpos - 1; ypos = ypos - 241;
- strcpy(vpl,"F");
- break;
- case SIDE_AREA : SetWindow3D(SIDE_ID,0);
- xpos = xpos - 241; ypos = ypos - 241;
- strcpy(vpl,"S");
- break;
- case TOP_AREA : SetWindow3D(TOP_ID,0);
- xpos = xpos - 1; ypos = ypos - 1;
- strcpy(vpl,"T");
- break;
- case ISO_AREA : SetWindow3D(ISO_ID,0);
- xpos = xpos - 241; ypos = ypos - 1;
- strcpy(vpl,"Iso");
- break;
- default: SetWindow3D(FRONT_ID,0);
- xpos = xpos - 1; ypos = ypos - 241;
- strcpy(vpl,"M");
- break;
- }
- FULLSCREEN_VIEW
- status++; // keep the compiler quiet!
- if (!SnapStatus)
- ScreenToWorld(xpos, xpos, &wx, &wy);
- else
- if (k < 3)
- GetGridPoint2D(grid[k],xpos, ypos, &wx, &wy);
-
- if (fabs(wx) < TOL) wx = 0.0;
- if (fabs(wy) < TOL) wy = 0.0;
- setcolor(15);
- setfillstyle(1,WHITE);
- bar3d(490,218,getmaxx(),218+15,0,0);
- bar3d(490,218+15+5,getmaxx(),218+15+15+5,0,0);
- bar3d(490,260,515,275,0,0);
- setcolor(0);
- if (k < 3) {
- sprintf(s,"%g",wx);
- outtextxy(490+2,218+2,s);
- sprintf(s,"%g",wy);
- outtextxy(490+2,218+15+5+2,s);
- }
- outtextxy(491, 262,vpl);
- setcolor(WHITE);
- }
-
- int WhereIsMouse(int x, int y)
- {
- // For VGA only
- if ((x > 1) && (x < 239) && (y > 241) && (y < 478)) return FRONT_AREA;
- if ((x > 241) && (x < 478) && (y > 241) && (y < 478)) return SIDE_AREA;
- if ((x > 1) && (x < 239) && (y > 1) && (y < 239)) return TOP_AREA;
- if ((x > 241) && (x < 478) && (y > 1) && (y < 239)) return ISO_AREA;
- return MENU_AREA;
- }
-
-
- void clearWindow(int vp)
- {
-
- switch(vp) {
- case 0: FRONT_VIEW break;
- case 1: SIDE_VIEW break;
- case 2: TOP_VIEW break;
- case 3: ISO_VIEW break;
- }
- MouseShow(0);
- clearviewport();
- MouseShow(1);
- }
-
-
- void SetWindow3D(int vp, int size)
- {
- ViewPort = vp;
- if (!size) {
- DeviceLeft = 1;
- DeviceTop = 1;
- DeviceRight = 238;
- DeviceBottom = 238;
- }
- else {
- DeviceLeft = 1;
- DeviceTop = 1;
- DeviceRight = getmaxy()-1;
- DeviceBottom = getmaxy()-1;
- }
- a = (DeviceRight-DeviceLeft)/2.0;
- b = DeviceLeft + a;
- c = (DeviceTop-DeviceBottom)/2.0;
- d = DeviceBottom + c;
- SetViewpoint();
- if (!size) {
- switch(vp) {
- case 0: FRONT_VIEW break;
- case 1: SIDE_VIEW break;
- case 2: TOP_VIEW break;
- case 3: ISO_VIEW break;
- }
- }
- else setviewport(1,1,getmaxy()-1,getmaxy()-1,1);
- }
-
-
-
- void DrawAxes(void)
- {
- POINT3D v1, v2;
- setlinestyle(SOLID_LINE,1,THICK_WIDTH);
- v1.x = 0.0; v1.y = 0.0; v1.z = 0.0;
- setcolor(RED);
- v2.x = 1.0; v2.y = 0.0; v2.z = 0.0;
- drawline3D(&v1, &v2);
- setcolor(GREEN);
- v2.x = 0.0; v2.y = 1.0; v2.z = 0.0;
- drawline3D(&v1, &v2);
- setcolor(BLUE);
- v2.x = 0.0; v2.y = 0.0; v2.z = 1.0;
- drawline3D(&v1, &v2);
- setcolor(WHITE);
- setlinestyle(SOLID_LINE,1,NORM_WIDTH);
- }
-
-
- float DegToRad(float deg) {
- return(deg * .017453293);
- }
-
- float RadToDeg(float rad) {
- return(rad * 57.29577951);
- }
-
- void InitGraphics(void)
- {
- int gdriver = VGA, gmode = VGAHI, errorcode;
- initgraph(&gdriver, &gmode, "");
- errorcode = graphresult();
- if (errorcode != grOk) /* an error occurred */
- {
- printf("Graphics error: %s\n", grapherrormsg(errorcode));
- printf("Press any key to halt:");
- getch();
- exit(1); /* terminate with an error code */
- }
- setviewport(0,0,getmaxx(),getmaxy(),1); /* sets viewport with line clipping */
- }
-
- void WorldToDevice(double xw, double yw, int *xpc, int *ypc)
- {
- *xpc = (int)(a * xw + b);
- *ypc = (int)(c * yw + d);
-
- }
-
- void ScreenToWorld(int mx, int my, float *wx, float *wy)
- {
- int v;
- v = ViewPort;
- if (ViewPort == 3) {
- *wx = (float)(mx - b)/a;
- *wy = (float)(my - d)/c;
- }
- else {
- *wx = ((1 - mx) * (World[v].Hmin-World[v].Hmax))/(float)(238-1) + World[v].Hmin ;
- *wy = ((1 - my) * (World[v].Vmax-World[v].Vmin))/(float)(238-1) + World[v].Vmax ;
- }
- }
-
-
- POINT3D add(POINT3D *a,POINT3D *b)
- {
- POINT3D t;
- t.x = a->x + b->x;
- t.y = a->y + b->y;
- t.z = a->z + b->z;
- return(t);
- }
-
-
- POINT3D subtract(POINT3D *at,POINT3D *from)
- {
- POINT3D t;
- t.x = at->x - from->x;
- t.y = at->y - from->y;
- t.z = at->z - from->z;
- return(t);
- }
-
- float mag(POINT3D *v)
- {
- return sqrt(v->x * v->x + v->y * v->y + v->z * v->z);
- }
-
-
- int equal(POINT3D *a, POINT3D *b)
- {
- return (a->x == b->x && a->y == b->y && a->z == b->z);
- }
-
-
- POINT3D multiply(POINT3D *v,float f)
- {
- POINT3D t;
- t.x = v->x * f;
- t.y = v->y * f;
- t.z = v->z * f;
- return(t);
- }
-
- POINT3D divide(POINT3D *v,float d)
- {
- POINT3D t;
- if (d == 0.0) {
- d = TOL;
- InfoBox("Error in DIVIDE function! Contact the authors. Save data!");
- }
- t.x = v->x / d;
- t.y = v->y / d;
- t.z = v->z / d;
- return(t);
- }
-
- POINT3D cross(POINT3D *v1, POINT3D *v2)
- {
- POINT3D t;
- t.x = v1->y * v2->z - v2->y * v1->z;
- t.y = v1->z * v2->x - v2->z * v1->x;
- t.z = v1->x * v2->y - v2->x * v1->y;
- return(t);
- }
-
-
- void SetViewpoint(void)
- {
- POINT3D temp,temp2;
-
- DVal = 1.0/tan(angle/2.0);
- temp2 = subtract(&at, &from);
- a3 = divide(&temp2, mag(&temp2));
- temp = cross(&up, &temp2);
- a1 = divide(&temp, mag(&temp));
- temp = cross(&a3, &a1);
- a2 = divide(&temp, mag(&temp));
- offset_x = -a1.x * from.x - a1.y * from.y - a1.z * from.z;
- offset_y = -a2.x * from.x - a2.y * from.y - a2.z * from.z;
- offset_z = -a3.x * from.x - a3.y * from.y - a3.z * from.z;
- }
-
- void World2DToDevice(POINT3D pp,int *xd, int *yd)
- {
- int c;
- POINT3D p;
- c = ViewPort;
- switch(c) {
- case 0: p.x = pp.x; p.y = pp.y; break;
- case 1: p.x = pp.z; p.y = pp.y; break;
- case 2: p.x = pp.x; p.y = pp.z; break;
- }
- *xd = (World[c].Hmin-p.x)*(238-1)/(World[c].Hmin-World[c].Hmax) + 1.5;
- *yd = (World[c].Vmax-p.y)*(238-1)/(World[c].Vmax-World[c].Vmin) + 1.5;
- }
-
- void drawline3D(POINT3D *v1, POINT3D *v2)
- {
-
- float x1, y1, z1, x2, y2, z2;
- int xpc1,ypc1,xpc2,ypc2;
-
- if (ViewPort ==3) {
- x1 = (v1->x * a1.x + a1.y * v1->y + a1.z * v1->z + offset_x)*DVal;
- y1 = (v1->x * a2.x + a2.y * v1->y + a2.z * v1->z + offset_y)*DVal;
- z1 = v1->x * a3.x + a3.y * v1->y + a3.z * v1->z + offset_z;
- x2 = (v2->x * a1.x + a1.y * v2->y + a1.z * v2->z + offset_x)*DVal;
- y2 = (v2->x * a2.x + a2.y * v2->y + a2.z * v2->z + offset_y)*DVal;
- z2 = v2->x * a3.x + a3.y * v2->y + a3.z * v2->z + offset_z;
- if(z1 !=0 && z2 !=0){
- WorldToDevice(x1/z1,y1/z1,&xpc1,&ypc1);
- WorldToDevice(x2/z2,y2/z2,&xpc2,&ypc2);
- }
- else{
- WorldToDevice(x1,y1,&xpc1,&ypc1);
- WorldToDevice(x2,y2,&xpc2,&ypc2);
- }
- line(xpc1,ypc1,xpc2,ypc2);
- }
- else {
- World2DToDevice(*v1,&xpc1, &ypc1);
- World2DToDevice(*v2,&xpc2, &ypc2);
- line(xpc1,ypc1,xpc2,ypc2);
- }
- }
-
- void drawpoint3D(POINT3D *v1)
- {
-
- float x1, y1, z1;
- int xpc1,ypc1;
- if (ViewPort ==3) {
- x1 = (v1->x * a1.x + a1.y * v1->y + a1.z * v1->z + offset_x)*DVal;
- y1 = (v1->x * a2.x + a2.y * v1->y + a2.z * v1->z + offset_y)*DVal;
- z1 = v1->x * a3.x + a3.y * v1->y + a3.z * v1->z + offset_z;
-
- if(z1 !=0 ) WorldToDevice(x1/z1,y1/z1,&xpc1,&ypc1);
- else WorldToDevice(x1,y1,&xpc1,&ypc1);
- circle(xpc1,ypc1,5);
- }
- else {
- World2DToDevice(*v1,&xpc1, &ypc1);
- circle(xpc1,ypc1,5);
- }
-
- }
-
-
- void drawsphere (int WinNum, POINT3D pc,float R)
- {
- POINT3D p1,p2;
- float v, u;
- int COUNT;
- if (WinNum == 2) {
- v = 0;
- COUNT = 0;
- for(u=DegToRad(0);u<=DegToRad(360);u+=DegToRad(15)) {
- p1.x = R * cos(u);
- p1.z = R * sin(u);
- p1.y = 0;
- p1.x = pc.x + p1.x;
- p1.y = pc.y + p1.y;
- p1.z = pc.z + p1.z;
-
- if( COUNT == 0) {
- p2 = p1;
- COUNT++;
- }
- else {
- drawline3D(&p1, &p2);
- p2 = p1;
- }
-
- }
- }
- if (WinNum == 0) {
- u = 0;
- COUNT = 0;
- for(v=DegToRad(0);v<=DegToRad(360);v+=DegToRad(15)) {
- p1.x = R * cos(v);
- p1.z = 0;
- p1.y = R * sin(v);
- p1.x = pc.x + p1.x;
- p1.y = pc.y + p1.y;
- p1.z = pc.z + p1.z;
-
- if( COUNT == 0) {
- p2 = p1;
- COUNT++;
- }
- else {
- drawline3D(&p1, &p2);
- p2 = p1;
- }
-
- }
- }
- if (WinNum == 1) {
- u = DegToRad(90);
- COUNT = 0;
- for(v=DegToRad(0);v<=DegToRad(360);v+=DegToRad(15)) {
- p1.x = 0;
- p1.z = R * cos(v);
- p1.y = R * sin(v);
- p1.x = pc.x + p1.x;
- p1.y = pc.y + p1.y;
- p1.z = pc.z + p1.z;
-
- if( COUNT == 0) {
- p2 = p1;
- COUNT++;
- }
- else {
- drawline3D(&p1, &p2);
- p2 = p1;
- }
-
- }
- }
- if (WinNum == 3) {
- for(v=DegToRad(-90);v<=DegToRad(90);v+=DegToRad(30)) {
- COUNT = 0;
- for(u=DegToRad(0);u<=DegToRad(360+30);u+=DegToRad(30)) {
- p1.x = R * cos(v) * cos(u);
- p1.z = R * cos(v) * sin(u);
- p1.y = R * sin(v);
- p1.x = pc.x + p1.x;
- p1.y = pc.y + p1.y;
- p1.z = pc.z + p1.z;
-
- if( COUNT == 0) {
- p2 = p1;
- COUNT++;
- }
- else {
- drawline3D(&p1, &p2);
- p2 = p1;
- }
-
- }
- }
-
- for(u=DegToRad(0);u<= DegToRad(360);u+=DegToRad(30)) {
- COUNT = 0;
- for(v=DegToRad(-90);v<=DegToRad(90+30);v+=DegToRad(30)) {
- p1.x = R * cos(v) * cos(u);
- p1.z = R * cos(v) * sin(u);
- p1.y = R * sin(v);
- p1.x = pc.x + p1.x;
- p1.y = pc.y + p1.y;
- p1.z = pc.z + p1.z;
-
- if( COUNT == 0) {
- p2 = p1;
- COUNT++;
- }
- else {
- drawline3D(&p1, &p2);
- p2 = p1;
- }
-
- }
- }
- }
- }
-
-
-
- int IsMouse()
- {
- inregs.x.ax = 0;
- int86(0x33,&inregs,&outregs);
- return(outregs.x.ax ? outregs.x.bx : 0);
- }
-
-
-
- int MouseClick()
- {
- int click = 0;
- inregs.x.ax = 5;
- inregs.x.bx = 1;
- int86(0x33,&inregs,&outregs);
- click = outregs.x.bx << 1;
- inregs.x.bx--;
- int86(0x33,&inregs,&outregs);
- return(click | outregs.x.bx);
- }
-
-
-
-
- void MouseXY(int *xpos,int *ypos)
- {
- inregs.x.ax = 3;
- int86(0x33,&inregs,&outregs);
- *xpos = outregs.x.cx;
- *ypos = outregs.x.dx;
- }
-
- void MouseShow(int toggle)
- {
- if (toggle) inregs.x.ax = 1;
- else inregs.x.ax = 2;
- int86(0x33,&inregs,&outregs);
- }
-
-
- Icon CreateIcon(int xo,int yo,int width,int height,int color,char * text)
- {
- Icon temp;
- temp.x = xo;
- temp.y = yo;
- temp.width = width;
- temp.height = height;
- temp.color = color;
- strcpy(temp.str,text);
- return(temp);
- }
-
- void DrawIcon(Icon ic)
- {
- int color;
- color = getcolor();
- MouseShow(0);
- setcolor(0);
- setfillstyle(1,ic.color);
- bar3d(ic.x,ic.y,ic.x+ic.width,ic.y+ic.height,0,0);
- rectangle(ic.x,ic.y,ic.x+ic.width,ic.y+ic.height);
- rectangle(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+ic.height-1);
- outtextxy(ic.x+2,ic.y + 5,ic.str);
- setcolor(15);
- line(ic.x,ic.y,ic.x+ic.width,ic.y);
- line(ic.x,ic.y,ic.x,ic.y+ic.height);
- line(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+1);
- line(ic.x+1,ic.y+1,ic.x+1,ic.y+ic.height-1);
- outtextxy(ic.x+1,ic.y + 4,ic.str);
- MouseShow(1);
- setcolor(color);
- }
-
- int IconCheck(Icon ikon,int xm,int ym)
- {
- if ((xm > ikon.x) && (xm < ikon.x + ikon.width) &&
- (ym > ikon.y) && (ym < ikon.y + ikon.height))
- return(1);
- else return(0);
- }
-
- void CreateIconColumn(int xo,int yo,int width,int height,int color,
- int spc, int num, Icon icon[],char **text)
- {
- int i,y;
- y = yo;
- for(i=0;i<num;i++) {
- icon[i] = CreateIcon(xo,y,width,height,color,text[i]);
- y += height + spc;
- }
- }
-
- POINTint World3DToDevice(POINT3D v1)
- {
- float x1, y1, z1;
- int xpc1,ypc1;
- POINTint tmp;
- if (ViewPort ==3) {
- x1 = (v1.x * a1.x + a1.y * v1.y + a1.z * v1.z + offset_x)*DVal;
- y1 = (v1.x * a2.x + a2.y * v1.y + a2.z * v1.z + offset_y)*DVal;
- z1 = v1.x * a3.x + a3.y * v1.y + a3.z * v1.z + offset_z;
-
- if(z1 !=0 ) WorldToDevice(x1/z1,y1/z1,&xpc1,&ypc1);
- else WorldToDevice(x1,y1,&xpc1,&ypc1);
- tmp.x = xpc1; tmp.y = ypc1; return (tmp);
- }
- else {
- World2DToDevice(v1,&xpc1, &ypc1);
- tmp.x = xpc1; tmp.y = ypc1; return (tmp);
- }
-
- }
-
- void drawpolygon (POINT3D *poly, int size)
- {
- POINTint p[6], p12,p32;
- int i, drawit, pp[14], count;
- long sum;
-
- if (SaveRAW) {
- for (i=1;i <= size-2;i++)
- fprintf (RAWfptr,"%g %g %g %g %g %g %g %g %g\n",
- poly[0].x,poly[0].y,poly[0].z,
- poly[i].x,poly[i].y,poly[i].z,
- poly[i+1].x,poly[i+1].y,poly[i+1].z);
- }
-
- for (i = 0; i < size; i++)
- p[i] = World3DToDevice(poly[i]);
-
- for(i=0,count=0; i<2*size; i+=2,count++) {
- pp[i] = p[count].x;
- pp[i+1] = p[count].y;
- }
-
- pp[i] = pp[0]; pp[i+1] = pp[1];
-
- if (!hide_backface)
- drawit = 1; /* Draw everything */
- else {
- /* find the "average" normal to the polygon */
- sum = 0;
- for (i = 1; i <= size-2; i++) {
- p12.x = p[i].x - p[0].x;
- p12.y = p[i].y - p[0].y;
- p32.x = p[i+1].x - p[0].x;
- p32.y = p[i+1].y - p[0].y;
-
- sum = sum + ((long)p12.x * (long)p32.y) -
- ((long)p12.y * (long)p32.x);
- }
-
- /* Only draw the front faces */
- drawit = (sum > 0);
- }
-
- if (drawit)
- fillpoly(size,pp);
- }
-
-
- /* Calculates the field strength of the blob at point 'p' */
- float BlobFunc (POINT3D p)
- {
- POINT3D dist;
- float field, r, r2, temp;
- int i;
-
- field = 0.0;
-
- for (i = 1; i <= bnum; i++) {
- dist.x = p.x - blobs[i].x;
- dist.y = p.y - blobs[i].y;
- dist.z = p.z - blobs[i].z;
-
- r = dist.x*dist.x + dist.y*dist.y + dist.z*dist.z;
- r2 = blobs[i].radius * blobs[i].radius;
-
- if (r < r2) {
- temp = (1.0 - r/r2);
- field += blobs[i].strength * temp*temp;
- }
- }
-
- return (field - threshold);
- }
-
-
- /* Allocate memory for the marching cubes algorithm */
- int AllocateCubes()
- {
- int i;
-
- level0 = malloc ((y_steps+1) * sizeof(SAMPLE *));
- if (level0 == NULL)
- return 0;
-
- for (i = 0; i < y_steps+1; i++) {
- level0[i] = malloc ((z_steps+1) * sizeof(SAMPLE));
- if (level0[i] == NULL)
- return 0;
- }
-
- level1 = malloc ((y_steps+1) * sizeof(SAMPLE *));
- if (level1 == NULL)
- return 0;
-
- for (i = 0; i < y_steps+1; i++) {
- level1[i] = malloc ((z_steps+1) * sizeof(SAMPLE));
- if (level1[i] == NULL)
- return 0;
- }
-
- return 1;
- }
-
-
- void FreeCubes()
- {
- int i;
-
- for (i = 0; i < y_steps+1; i++)
- free (level0[i]);
- free (level0);
-
- for (i = 0; i < y_steps+1; i++)
- free (level1[i]);
- free (level1);
- }
-
-
- void SampleLevel (SAMPLE **level, int ix,
- POINT3D *vmin, POINT3D *vmax)
- {
- POINT3D v;
- int iy, iz;
-
- v.x = (float)ix/x_steps * vmin->x +
- (1.0 - (float)ix/x_steps)*vmax->x;
-
- for (iy = 0; iy <= y_steps; iy++) {
- v.y = (float)iy/y_steps * vmin->y +
- (1.0 - (float)iy/y_steps)*vmax->y;
-
- for (iz = 0; iz <= z_steps; iz++) {
- v.z = (float)iz/z_steps * vmin->z +
- (1.0 - (float)iz/z_steps)*vmax->z;
-
- level[iy][iz].loc = v;
- level[iy][iz].value = BlobFunc (v);
- }
- }
- }
-
-
- /* Break the blob up into a mesh and display it */
- int CreateBlobs()
- {
- int i, ix, iy, iz;
- BLOB b;
- SAMPLE **temp;
- POINT3D vmin = {+1e30, +1e30, +1e30};
- POINT3D vmax = {-1e30, -1e30, -1e30};
-
- clearviewport();
- setfillstyle(1,7);
-
- /* Find the extents of the shape */
- for (i = 1; i <= bnum; i++) {
- b = blobs[i];
- if (b.x - b.radius < vmin.x) vmin.x = b.x - b.radius;
- if (b.x + b.radius > vmax.x) vmax.x = b.x + b.radius;
- if (b.y - b.radius < vmin.y) vmin.y = b.y - b.radius;
- if (b.y + b.radius > vmax.y) vmax.y = b.y + b.radius;
- if (b.z - b.radius < vmin.z) vmin.z = b.z - b.radius;
- if (b.z + b.radius > vmax.z) vmax.z = b.z + b.radius;
- }
-
- if (!AllocateCubes()) {
- closegraph();
- printf("Not enough memory for marching cubes.");
- exit(1);
- }
-
- SampleLevel (level0, 0, &vmin, &vmax);
-
- for (ix = 1; ix <= x_steps; ix++) {
- SampleLevel (level1, ix, &vmin, &vmax);
-
- for (iy = 0; iy < y_steps; iy++)
- for (iz = 0; iz < z_steps; iz++)
- CubeIntersect (iy, iz);
-
- temp = level0;
- level0 = level1;
- level1 = temp;
- }
-
- FreeCubes();
-
- return 1;
- }
-
-
- void CubeIntersect (int iy, int iz)
- {
- SAMPLE cube[8];
- int i, j, polysize, numline;
- PAIR3D line[12], temp;
- POINT3D poly[12];
-
- cube[0] = level0[iy][iz];
- cube[1] = level1[iy][iz];
- cube[2] = level0[iy+1][iz];
- cube[3] = level1[iy+1][iz];
- cube[4] = level0[iy][iz+1];
- cube[5] = level1[iy][iz+1];
- cube[6] = level0[iy+1][iz+1];
- cube[7] = level1[iy+1][iz+1];
-
- /* Analyze each of the 6 faces of the cube one at a time. For
- each face that was intersected save the intersection line */
-
- numline = 0;
-
- FaceIntersect (cube, 0, 1, 3, 2, line, &numline);
- FaceIntersect (cube, 4, 6, 7, 5, line, &numline);
- FaceIntersect (cube, 0, 2, 6, 4, line, &numline);
- FaceIntersect (cube, 1, 5, 7, 3, line, &numline);
- FaceIntersect (cube, 0, 4, 5, 1, line, &numline);
- FaceIntersect (cube, 2, 3, 7, 6, line, &numline);
-
- if (numline > 0) {
- /* Sort the line segments into polygons */
- polysize = 0;
-
- for (i = 0; i < numline; i++) {
- poly[polysize++] = line[i].p1;
-
- for (j = i+1; j < numline; j++) {
- if (equal (&line[j].p1, &line[i].p2)) {
- temp = line[j];
- line[j] = line[i+1];
- line[i+1] = temp;
- break;
- }
- }
-
- if (j >= numline) {
- drawpolygon (poly, polysize);
- polysize = 0;
- }
- }
- }
- }
-
-
- /* Analyze a cube face for blob intersections. Intersections are
- detected by looking for positive to negative field strength
- changes between adjacent corners. If an intersection is found
- then the coords of the line segment(s) are added to array line
- and *numline is increased */
- void FaceIntersect (SAMPLE *cube, int a, int b, int c, int d,
- PAIR3D *line, int *numline)
- {
- POINT3D points[4], vcenter;
- float center;
- int sign[4];
- int l1, l2, l3, l4;
- int index = 0;
-
- /* Check face edge a-b */
- if (cube[a].value * cube[b].value < 0.0) {
- sign[index] = (cube[b].value >= 0.0);
- EdgeIntersect (&points[index++], &cube[a], &cube[b]);
- }
-
- /* Check face edge b-c */
- if (cube[b].value * cube[c].value < 0.0) {
- sign[index] = (cube[c].value >= 0.0);
- EdgeIntersect (&points[index++], &cube[b], &cube[c]);
- }
-
- /* Check face edge c-d */
- if (cube[c].value * cube[d].value < 0.0) {
- sign[index] = (cube[d].value >= 0.0);
- EdgeIntersect (&points[index++], &cube[c], &cube[d]);
- }
-
- /* Check face edge d-a */
- if (cube[d].value * cube[a].value < 0.0) {
- sign[index] = (cube[a].value >= 0.0);
- EdgeIntersect (&points[index++], &cube[d], &cube[a]);
- }
-
- /* One line segment */
- if (index == 2) {
- if (sign[0] > 0) { /* Get the line direction right */
- line[*numline].p1 = points[0];
- line[*numline].p2 = points[1];
- }
- else {
- line[*numline].p1 = points[1];
- line[*numline].p2 = points[0];
- }
-
- (*numline)++;
- }
- /* Two line segments */
- else if (index == 4) {
- /* Sample the center of the face to determine which points
- to connect */
- vcenter = add (&cube[a].loc, &cube[b].loc);
- vcenter = add (&vcenter, &cube[c].loc);
- vcenter = add (&vcenter, &cube[d].loc);
- vcenter = multiply (&vcenter, 0.25);
- center = BlobFunc(vcenter);
-
- /* Does the sign of the center sample match the
- sign of the upper left corner? */
- if ((center >= 0.0) != sign[0])
- { l1 = 0; l2 = 1; l3 = 2; l4 = 3; }
- else
- { l1 = 1; l2 = 2; l3 = 3; l4 = 0; }
-
- if (sign[l1] > 0) { /* Get the line direction right */
- line[*numline].p1 = points[l1];
- line[*numline].p2 = points[l2];
- }
- else {
- line[*numline].p1 = points[l2];
- line[*numline].p2 = points[l1];
- }
-
- (*numline)++;
-
- if (sign[l3] > 0) {
- line[*numline].p1 = points[l3];
- line[*numline].p2 = points[l4];
- }
- else {
- line[*numline].p1 = points[l4];
- line[*numline].p2 = points[l3];
- }
-
- (*numline)++;
- }
- }
-
-
- void EdgeIntersect (POINT3D *v, SAMPLE *a, SAMPLE *b)
- {
- POINT3D vtemp;
-
- if (a->value > b->value) {
- vtemp = subtract (&a->loc, &b->loc);
- vtemp = multiply (&vtemp, a->value/(a->value - b->value));
- *v = subtract (&a->loc, &vtemp);
- }
- else {
- vtemp = subtract (&b->loc, &a->loc);
- vtemp = multiply (&vtemp, b->value/(b->value - a->value));
- *v = subtract (&b->loc, &vtemp);
- }
- }
-